import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Like, Not, Repository } from 'typeorm';
import { Permission } from './entities/permission.entity';
import { CreatePermissionDto } from './dto/create-permission.dto';
import { UpdatePermissionDto } from './dto/update-permission.dto';

@Injectable()
export class PermissionService {
  @InjectRepository(Permission)
  private permissionRepository: Repository<Permission>;

  async create(createPermissionDto: CreatePermissionDto) {
    const { code, description } = createPermissionDto;

    const existPermission = await this.permissionRepository.findOne({
      where: { code },
    });

    if (existPermission) {
      throw new HttpException('权限编码已存在', HttpStatus.BAD_REQUEST);
    }

    const permission = new Permission();
    permission.code = code;
    permission.description = description;

    try {
      await this.permissionRepository.save(permission);
      return '创建成功';
    } catch (e) {
      throw new HttpException('创建失败', HttpStatus.INTERNAL_SERVER_ERROR);
    }
  }

  async findAll(
    pageNum: number,
    pageSize: number,
    code?: string,
    description?: string,
  ) {
    const skipCount = (pageNum - 1) * pageSize;

    const condition: Record<string, any> = {};
    if (code) {
      condition.code = Like(`%${code}%`);
    }
    if (description) {
      condition.description = Like(`%${description}%`);
    }

    const [permissions, total] = await this.permissionRepository.findAndCount({
      where: condition,
      skip: skipCount,
      take: pageSize,
    });

    return {
      permissions,
      total,
    };
  }

  async findOne(id: number) {
    const permission = await this.permissionRepository.findOne({
      where: { id },
    });

    if (!permission) {
      throw new HttpException('权限不存在', HttpStatus.BAD_REQUEST);
    }

    return permission;
  }

  async update(id: number, updatePermissionDto: UpdatePermissionDto) {
    const { code, description } = updatePermissionDto;

    const permission = await this.permissionRepository.findOne({
      where: { id },
    });

    if (!permission) {
      throw new HttpException('权限不存在', HttpStatus.BAD_REQUEST);
    }

    if (code) {
      const existPermission = await this.permissionRepository.findOne({
        where: { code, id: Not(id) },
      });

      if (existPermission) {
        throw new HttpException('权限编码已存在', HttpStatus.BAD_REQUEST);
      }

      permission.code = code;
    }

    if (description) {
      permission.description = description;
    }

    try {
      await this.permissionRepository.save(permission);
      return '更新成功';
    } catch (e) {
      throw new HttpException('更新失败', HttpStatus.INTERNAL_SERVER_ERROR);
    }
  }

  async remove(id: number) {
    const permission = await this.permissionRepository.findOne({
      where: { id },
      relations: ['roles'],
    });

    if (!permission) {
      throw new HttpException('权限不存在', HttpStatus.BAD_REQUEST);
    }

    if (permission.roles && permission.roles.length > 0) {
      throw new HttpException(
        '该权限已被角色使用，无法删除',
        HttpStatus.BAD_REQUEST,
      );
    }

    try {
      await this.permissionRepository.remove(permission);
      return '删除成功';
    } catch (e) {
      throw new HttpException('删除失败', HttpStatus.INTERNAL_SERVER_ERROR);
    }
  }
}
